home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / CBGRX103.ZIP / contrib / libgrx / src / bestfont.c < prev    next >
Text File  |  1993-12-06  |  5KB  |  187 lines

  1. /**
  2.  ** BESTFONT.C
  3.  **
  4.  **  Copyright (C) 1992, Csaba Biegl
  5.  **    820 Stirrup Dr, Nashville, TN, 37221
  6.  **    csaba@vuse.vanderbilt.edu
  7.  **
  8.  **  This file is distributed under the terms listed in the document
  9.  **  "copying.cb", available from the author at the address above.
  10.  **  A copy of "copying.cb" should accompany this file; if not, a copy
  11.  **  should be available from where this file was obtained.  This file
  12.  **  may not be distributed without a verbatim copy of "copying.cb".
  13.  **  You should also have received a copy of the GNU General Public
  14.  **  License along with this program (it is in the file "copying");
  15.  **  if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  16.  **  Cambridge, MA 02139, USA.
  17.  **
  18.  **  This program is distributed in the hope that it will be useful,
  19.  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  **  GNU General Public License for more details.
  22.  **/
  23.  
  24. #include "grx.h"
  25. #include "libgrx.h"
  26. #include "grxfile.h"
  27. #include "gmalloc.h"
  28.  
  29. #include <string.h>
  30. #include <stdio.h>
  31. #include <io.h>
  32.  
  33.  
  34. #define FNT_USABLE    fnt_internal        /* reuse this flag ! */
  35.  
  36.  
  37. static GrFont *fontDB;
  38. static int DBsize;
  39. static int loaded = FALSE;
  40.  
  41.  
  42. static int load_fontDB(void)
  43. {
  44.     FntDirHdr hdr;
  45.     char fullname[200];
  46.     int  file,size;
  47.  
  48.     _GrGetFname("fonts.dir",_GrFontPath,FNTENV,"",fullname);
  49.     if((file = _GrFileOpen(fullname)) == EOF) return(FALSE);
  50.     if((read(file,&hdr,sizeof(FntDirHdr)) != sizeof(FntDirHdr)) ||
  51.        (hdr.magic != FONTDIR_MAGIC) ||
  52.        ((size = sizeof(GrFont) * (int)hdr.numentries) <= 0) ||
  53.        ((fontDB = _GrMalloc(size)) == NULL) ||
  54.        (read(file,fontDB,size) != size)) {
  55.         if(fontDB != NULL) _GrFree(fontDB);
  56.         _GrFileClose(file);
  57.         return(FALSE);
  58.     }
  59.     _GrFileClose(file);
  60.     DBsize = (int)hdr.numentries;
  61.     return(loaded = TRUE);
  62. }
  63.  
  64. static int match_aux(char *pattern,char *string)
  65. {
  66.     for( ; ; ) {
  67.         switch(*pattern) {
  68.           case '\0':
  69.           case ':':
  70.         return((*string == '\0') ? TRUE : FALSE);
  71.           case '?':
  72.         if(*string == '\0') return(FALSE);
  73.         pattern++;
  74.         string++;
  75.         break;
  76.           case '*':
  77.         for( ; ; ) {
  78.             switch(*++pattern) {
  79.               case '\0':
  80.               case ':':
  81.             return(TRUE);
  82.               case '?':
  83.             if(*string == '\0') return(FALSE);
  84.             string++;
  85.             continue;
  86.               case '*':
  87.             continue;
  88.               default:
  89.             break;
  90.             }
  91.             break;
  92.         }
  93.         for( ; ; ) {
  94.             string = strchr(string,*pattern);
  95.             if(string == NULL) return(FALSE);
  96.             if(match_aux(pattern,string)) return(TRUE);
  97.             string++;
  98.         }
  99.           default:
  100.         if(*pattern != *string) return(FALSE);
  101.         string++;
  102.         pattern++;
  103.         }
  104.     }
  105. }
  106.  
  107. static int match(char *pattern,char *string)
  108. {
  109.     while(*pattern != '\0') {
  110.         if(match_aux(pattern,string)) return(TRUE);
  111.         pattern = strchr(pattern,':');
  112.         if(pattern == NULL) return(FALSE);
  113.         pattern++;
  114.     }
  115.     return(FALSE);
  116. }
  117.  
  118. GrTextOption *GrFindBestFont(int width,int height,int magnify,char *family,GrTextOption *where)
  119. {
  120.     GrFont *f;
  121.     int error = TRUE;
  122.     int found = (-1);
  123.     int ii,minerr;
  124.  
  125.     if(!loaded && !load_fontDB()) return(NULL);
  126.     for(f = fontDB,ii = 0; ii < DBsize; f++,ii++) {
  127.         if((f->fnt_height <= height) &&
  128.            (!f->fnt_isfixed || (f->fnt_width <= width)) &&
  129.            (match(family,f->fnt_family))) {
  130.         f->FNT_USABLE = TRUE;
  131.         error = FALSE;
  132.         if((f->fnt_height == height) &&
  133.            (!f->fnt_isfixed || (f->fnt_width == width))) {
  134.             magnify = FALSE;
  135.             found   = ii;
  136.             break;
  137.         }
  138.         }
  139.         else f->FNT_USABLE = FALSE;
  140.     }
  141.     if(error) return(NULL);
  142.     if(found < 0) {
  143.         minerr = 32000;
  144.         for(f = fontDB,ii = 0; ii < DBsize; f++,ii++) {
  145.         if(!f->FNT_USABLE) continue;
  146.         if(!magnify) {
  147.             error = height - f->fnt_height;
  148.             if(f->fnt_isfixed) error += width - f->fnt_width;
  149.         }
  150.         else {
  151.             int magn = height / f->fnt_height;
  152.             int size = magn * f->fnt_height;
  153.             error = (height - size) + (2 * --magn);
  154.             if(f->fnt_isfixed) {
  155.             magn = width / f->fnt_width;
  156.             size = magn * f->fnt_width;
  157.             error += (width - size) + (2 * --magn);
  158.             }
  159.         }
  160.         if(error < minerr) {
  161.             found  = ii;
  162.             minerr = error;
  163.         }
  164.         }
  165.     }
  166.     f = GrLoadFont(fontDB[found].fnt_name);
  167.     if(f == NULL) return(NULL);
  168.     if(where == NULL) {
  169.         where = _GrMalloc(sizeof(GrTextOption));
  170.         if(where == NULL) return(NULL);
  171.     }
  172.     memset(where,0,sizeof(GrTextOption));
  173.     where->txo_font = f;
  174.     if(!magnify) {
  175.         where->txo_xmag = 1;
  176.         where->txo_ymag = 1;
  177.     }
  178.     else {
  179.         where->txo_ymag = height / f->fnt_height;
  180.         where->txo_xmag = f->fnt_isfixed ?
  181.         width / f->fnt_width :
  182.         where->txo_ymag;
  183.     }
  184.     return(where);
  185. }
  186.  
  187.